package telnet

import (
	"bufio"
	"fmt"
	"net"
	"strings"
)

// 链接的会话逻辑
//  会话入口，传入连接和退出用的通道。handle Session() 函数被并发执行。
func handleSession(conn net.Conn, exitChan chan int) {
	fmt.Println("Session started:")

	// 创建一个网络连接数据的读取器
	// bufio.NewReader 创建一个网络数据读取器，这个 Reader 将输入数据的读取过程进行封装，方便我们迅速获取到需要的数据。
	reader := bufio.NewReader(conn)

	// 接收数据的循环
	// 从 Socket 连接，通过 reader 读取器读取封包，处理封包后需要继续读取从网络发送过来的下一个封包，因此需要一个会话处理循环
	for {
		// 读取字符串，直到遇到回车返回
		// reader.ReadString() 方法进行封包读取, 内部会自动处理粘包过程，直到下一个回车符到达后返回数据。
		//		这里认为封包来自 Telnet，每个指令以回车换行符（“\r\n”）结尾。
		str, err := reader.ReadString('\n')

		// 数据读取正确
		if err == nil {
			// 去掉字符串尾部的回车
			str = strings.TrimSpace(str)

			// 处理 Telne 指令
			// 将 str 字符串传入 Telnet 指令处理函数 processTelnetCommand() 中，同时传入退出控制通道 exitChan。
			// 		当这个函数返回 false 时，表示需要关闭当前连接。
			if !processTelnetCommand(str, exitChan) {
				conn.Close()
				break
			}

			// Echo 逻辑，发什么数据，原样返回
			// 将有效数据通过 conn 的 Write() 方法写入，同时在字符串尾部添加回车换行符（“\r\n”），数据将被 Socket 发送给连接方。
			conn.Write([]byte(str + "\r\n"))
		} else {
			// 发生错误
			fmt.Println("Session closed")
			conn.Close()
			break
		}
	}
}
